﻿#include <iostream>
#include <string>
using namespace std;
// 电视机
class TV
{
protected:
  string m_brand;

public:
  TV(const string &brand) : m_brand(brand) {}
  ~TV() {}
  string getName()
  {
    return m_brand;
  }
  void Start()
  {
    cout << m_brand << "TV starting ..."
         << "\n"
         << "Start successful! " << endl;
  }
  void Off()
  {
    cout << m_brand << " TV Shuting down ..."
         << "\n"
         << "Power off !" << endl;
  }
};
// 冰箱
class Fridge
{
protected:
  string m_brand;
  double m_temperation;

public:
  Fridge(const string &brand) : m_brand(brand) {}
  ~Fridge() {}
  string getName()
  {
    return m_brand;
  }
  void Start()
  {
    cout << m_brand << "Fridge starting ..."
         << "\n"
         << "Start successful! " << endl;
  }
  void Off()
  {
    cout << m_brand << " Fridge Shuting down ..."
         << "\n"
         << "Power off !" << endl;
  }
  void attemperation(double tem)
  {
    if (-12.0 < tem && tem > 10)
    {
      cout << "Settings failed!" << endl;
    }
    else
    {
      cout << "Settings successful!"
           << "Current tempration is: " << tem << endl;
      m_temperation = tem;
    }
  }
};
// 洗衣机
class Washer
{
protected:
  string m_brand;

public:
  Washer(const string &brand) : m_brand(brand) {}
  Washer() = default;
  string getName()
  {
    return m_brand;
  }
  void Start()
  {
    cout << m_brand << "Washer starting ..."
         << "\n"
         << "Start successful! " << endl;
  }
  void Off()
  {
    cout << m_brand << " Washer Shuting down ..."
         << "\n"
         << "Power off !" << endl;
  }
  void washing()
  {
    cout << "Washing clothes ..." << endl;
  }
};
// 外观者抽象类，提供接口，可拓展性强
class AbApperance
{
protected:
  TV *m_tv = nullptr;

public:
  AbApperance() = default;
  AbApperance(TV *tv) : m_tv(tv) {}

  void show()
  {
    cout << (m_tv != nullptr ? m_tv->getName() : "") << "\n";
  }
};
class Appearance01 : public AbApperance
{
protected:
  Fridge *m_fridge = nullptr;

public:
  using AbApperance::AbApperance;
  Appearance01() = default;
  Appearance01(TV *tv, Fridge *fridge) : AbApperance(tv), m_fridge(fridge) {}

  void show()
  {
    AbApperance::show();
    cout << (m_fridge != nullptr ? m_fridge->getName() : "") << "\n";
  }
};
class Appearance02 : public Appearance01
{
protected:
  Washer *m_washer = nullptr;

public:
  Appearance02(TV *tv, Fridge *fridge, Washer *washer) : Appearance01(tv, fridge), m_washer(washer) {}

  void show()
  {
    Appearance01::show();
    cout << (m_washer == nullptr ? "" : m_washer->getName()) << endl;
  }
};
int main()
{

  TV *xiaomiTV = new TV("XiaoMi");
  Fridge *haierFridge = new Fridge("Haier");
  Washer *tongshuaiWasher = new Washer("Tongshuai");
  Appearance02 *appearance02 = new Appearance02(xiaomiTV, haierFridge, tongshuaiWasher);
  appearance02->show();
  return 0;
}